package com.ych.modules.common.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ych.SDK.alibaba.ossSDK.AliOssUtil;
import com.ych.modules.api.authorInfc.jackpot.service.JackpotService;
import com.ych.modules.api.authorInfc.job.entity.AuditReceiveJobEntity;
import com.ych.modules.api.authorInfc.job.entity.QueryPersonJobEntity;
import com.ych.modules.base.dbEntity.*;
import com.ych.modules.base.service.*;
import com.ych.modules.common.entity.query.QueryReceiveJobEntity;
import com.ych.modules.common.entity.query.QueryUserJobEntity;
import com.ych.modules.common.service.UserJobService;
import com.ych.utils.TLMap;
import com.ych.utils.UUID;
import com.ych.utils.beanToMap.BeanMapUtil;
import com.ych.utils.mysqlPageUtil.PageUtils;
import com.ych.utils.mysqlPageUtil.Query;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2021/3/10
 * Time: 14:29
 * Description:
 */
@Service
public class UserJobServiceImpl implements UserJobService {
    @Autowired
    private ITUserJobService     itUserJobService;
    @Autowired
    private ITJobStepService     itJobStepService;
    @Autowired
    private AliOssUtil           aliOssUtil;
    @Autowired
    private ITUserAccountService itUserAccountService;
    @Autowired
    private ITJobConcernService  itJobConcernService;
    @Autowired
    private ITJobReceiveService  itJobReceiveService;
    @Autowired
    private ITSysImgService      itSysImgService;
    @Autowired
    private ITUserInfoService    itUserInfoService;
    @Autowired
    private JackpotService       jackpotService;


    @Override
    public TUserJobEntity getUserJob(String jobId) {
        TUserJobEntity jobEntity = itUserJobService.selectById(jobId);
        if (null == jobEntity) {
            throw new RuntimeException("任务不存在！");
        }
        //扩展任务步骤
        this.extendsJobStep(jobEntity);
        this.extendsCreateUserInfo(jobEntity);
        //扩展是否关注和是否报名
        this.extendsConcernReceiveStatus(jobEntity);
        return jobEntity;
    }

    /**
     * 扩展关注和是否领取报名状态
     *
     * @param jobEntity
     */
    private void extendsConcernReceiveStatus(TUserJobEntity jobEntity) {
        jobEntity.setIsConcern("1");//没有关注
        jobEntity.setIsReceive("1");//没有领取参与
        Wrapper<TJobConcernEntity> concernWrapper = new EntityWrapper<TJobConcernEntity>()
                .where("1=1")
                .eq("user_id", TLMap.getUserId())//当前登录用户是否关注该项目
                .eq("job_id", jobEntity.getJobId());
        int concern = itJobConcernService.selectCount(concernWrapper);
        if (0 != concern) {
            jobEntity.setIsConcern("0");//关注了
        }
        Wrapper<TJobReceiveEntity> receiveWrapper = new EntityWrapper<TJobReceiveEntity>()
                .where("1=1")
                .eq("user_id", TLMap.getUserId())
                .eq("job_id", jobEntity.getJobId());
        TJobReceiveEntity receiveEntity = itJobReceiveService.selectOne(receiveWrapper);
        if (null != receiveEntity) {
            jobEntity.setIsReceive("0");//领取参与了
        }
        //把实体列表返回去
        jobEntity.setReceiveEntity(receiveEntity);
    }

    @Override
    public Page<TUserJobEntity> listUserJob(QueryUserJobEntity entity) {
        Wrapper<TUserJobEntity> wrapper = new EntityWrapper<TUserJobEntity>()
                .where("1=1")
                .eq(StringUtils.isNotBlank(entity.getStatus()), "status", entity.getStatus())
                .eq(StringUtils.isNotBlank(entity.getUserId()), "user_id", entity.getUserId());
        switch (entity.getOrderType()) {
            case "0":
                wrapper.orderBy("create_time desc");
                break;
            case "1":
                wrapper.orderBy("amount desc");
                break;
            default:
                break;
        }
        Page<TUserJobEntity> page = itUserJobService.selectPage(new Query<TUserJobEntity>(BeanMapUtil.toPageQuery(entity)).getPage(), wrapper);
        List<TUserJobEntity> list = new ArrayList<>();
        for (TUserJobEntity jobEntity : page.getRecords()) {
            this.extendsJobStep(jobEntity);
            this.extendsToAudit(jobEntity);//扩展待审核的任务数量
            this.extendsCreateUserInfo(jobEntity);//扩展发布用户信息
            list.add(jobEntity);
        }
        page.setRecords(list);
        return page;
    }

    /**
     * 扩展发布用户信息
     *
     * @param jobEntity
     */
    private void extendsCreateUserInfo(TUserJobEntity jobEntity) {
        //扩展发布者信息
        TUserInfoEntity userInfoEntity = itUserInfoService.selectById(jobEntity.getUserId());
        jobEntity.setUserName(userInfoEntity.getUserName());
        jobEntity.setUserHeadUrl(aliOssUtil.getOssObjectDownAuthUrl(userInfoEntity.getUserHeadUrl()));
    }

    /**
     * 扩展待审核的任务数量
     *
     * @param jobEntity
     */
    private void extendsToAudit(TUserJobEntity jobEntity) {
        Wrapper<TJobReceiveEntity> wrapper = new EntityWrapper<TJobReceiveEntity>()
                .where("1=1")
                .eq("job_id", jobEntity.getJobId())
                .eq("audit_status_type", "10010002");//待审核
        Integer count = itJobReceiveService.selectCount(wrapper);
        jobEntity.setToAuditCount(count);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void createJob(TUserJobEntity jobEntity) {
        this.validateAddJobParam(jobEntity);
        this.validateAccountCoinAmount(jobEntity.getPayAmount());
        jobEntity.setJobId(UUID.randomUUID());
        jobEntity.setUserId(TLMap.getUserId());
        jobEntity.setCreateTime(new Date());
        jobEntity.setResidueNumber(jobEntity.getNumber());//剩余数量初始就为总数量
        //支付金额设置
//        jobEntity.setPayAmount();
        jobEntity.setRechargeStatusType("10003002");//直接就是支付成功
        itUserJobService.insert(jobEntity);
        //添加任务步骤
        for (int i = 0; i < jobEntity.getStepList().size(); i++) {
            //添加任务步骤
            this.addJobStep(i, jobEntity.getStepList().get(i), jobEntity.getJobId());
        }
        itUserAccountService.alterGoldCoinAmount("10000002", "10001005", jobEntity.getUserId(), jobEntity.getJobId(), jobEntity.getPayAmount());
        //将金币按比例写入奖池
        try {
            //支付金额减去要发给领取任务的用户的金额，就是要分到奖池的金额
            BigDecimal amount = jobEntity.getPayAmount()
                    .subtract(jobEntity.getAmount()
                            .multiply(new BigDecimal(jobEntity.getNumber().toString())));
            //10012002：任务发布
            jackpotService.addAmountToJackpot("10012002", amount, jobEntity.getJobId(),null);
        } catch (Exception e) {
            //不阻断正常流程
        }
    }

    /**
     * 校验账户金币余额是否足以购买项目
     *
     * @param payAmount
     */
    private void validateAccountCoinAmount(BigDecimal payAmount) {
        TUserAccountEntity accountEntity = itUserAccountService.selectById(TLMap.getUserId());
        if (payAmount.compareTo(accountEntity.getGoldCoinAmount()) == 1) {
            throw new RuntimeException("账户金币余额不足，请先购置金币");
        }
    }

    /**
     * 添加任务步骤
     *
     * @param i          步骤数，第几步
     * @param stepEntity 步骤实体
     * @param jobId      任务id
     */
    private void addJobStep(int i, TJobStepEntity stepEntity, String jobId) {
        stepEntity.setId(UUID.randomUUID());
        stepEntity.setJobId(jobId);
        stepEntity.setImgUrl(aliOssUtil.getRelativePath(stepEntity.getImgUrl()));
        stepEntity.setStatus("0");
        stepEntity.setStepNum(i);
        itJobStepService.insert(stepEntity);
    }

    @Override
    public void concernJob(String jobId) {
        TUserJobEntity jobEntity = itUserJobService.selectById(jobId);
        if (null == jobEntity) {
            throw new RuntimeException("关注任务不存在！");
        }
        //判断是否已经关注过了，点过了就取消关注
        Wrapper<TJobConcernEntity> wrapper = new EntityWrapper<TJobConcernEntity>()
                .where("1=1")
                .eq("user_id", TLMap.getUserId())
                .eq("job_id", jobId);
        TJobConcernEntity jobConcernEntity = itJobConcernService.selectOne(wrapper);
        if (null != jobConcernEntity) {
            //删除这个关注
            itJobConcernService.deleteById(jobConcernEntity.getId());
            return;
        }
        TJobConcernEntity concernEntity = new TJobConcernEntity();
        concernEntity.setId(UUID.randomUUID());
        concernEntity.setCreateTime(new Date());
        concernEntity.setJobId(jobId);
        concernEntity.setUserId(TLMap.getUserId());
        itJobConcernService.insert(concernEntity);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void receiveJob(TJobReceiveEntity receiveEntity) {
        TUserJobEntity entity = itUserJobService.selectById(receiveEntity.getJobId());
        if (null == entity) {
            throw new RuntimeException("领取目标任务不存在！");
        }
        if (entity.getResidueNumber() <= 0) {
            throw new RuntimeException("任务剩余名额为零！");
        }
        //校验是否已经领取过这个任务了
        this.validateIsReceived(receiveEntity);
        receiveEntity.setId(UUID.randomUUID());
        receiveEntity.setUserId(TLMap.getUserId());
        receiveEntity.setCreateTime(new Date());
        receiveEntity.setAuditStatusType("10010001");//待提交审核
        receiveEntity.setStatus("0");//正常
        receiveEntity.setAmount(entity.getAmount());//每份任务奖励金额
        itJobReceiveService.insert(receiveEntity);
        //任务名额减一
        itUserJobService.modifyJobResidueNumber(entity.getJobId(), -1);
    }

    /**
     * 校验是否已经领取过这个任务了
     *
     * @param receiveEntity
     */
    private void validateIsReceived(TJobReceiveEntity receiveEntity) {
        Wrapper<TJobReceiveEntity> wrapper = new EntityWrapper<TJobReceiveEntity>()
                .where("1=1")
                .eq("job_id", receiveEntity.getJobId())
                .eq("user_id", TLMap.getUserId());
        int count = itJobReceiveService.selectCount(wrapper);
        if (count > 0) {
            throw new RuntimeException("请勿重复领取");
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void submitReceiveJob(TJobReceiveEntity receiveEntity) {
        Wrapper<TJobStepEntity> wrapper = new EntityWrapper<TJobStepEntity>()
                .where("1=1")
                .eq("job_id", receiveEntity.getJobId());
        Integer stepCount = itJobStepService.selectCount(wrapper);
        if (stepCount > receiveEntity.getStepImgList().size()) {
            throw new RuntimeException("请上传完整的步骤所需图片！");
        }
        TJobReceiveEntity jobReceiveEntity = itJobReceiveService.selectById(receiveEntity.getId());
        if (null == jobReceiveEntity) {
            throw new RuntimeException("待提交的领取任务不存在！");
        }
        if (!"10010001".equals(jobReceiveEntity.getAuditStatusType())
                && !"10010005".equals(jobReceiveEntity.getAuditStatusType())) {
            throw new RuntimeException("不为待提交或不通过补交！");
        }
        for (int i = 0; i < receiveEntity.getStepImgList().size(); i++) {
            itJobReceiveService.addStepImg(receiveEntity.getId(), i, receiveEntity.getStepImgList().get(i));
        }
        receiveEntity.setAuditStatusType("10010002");//设置为待审核
        itJobReceiveService.updateById(receiveEntity);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void auditReceiveJob(AuditReceiveJobEntity entity) {
        TJobReceiveEntity receiveEntity = itJobReceiveService.selectById(entity.getId());
        if (null == receiveEntity) {
            throw new RuntimeException("待处理审核不存在！");
        }
        if (!"10010002".equals(receiveEntity.getAuditStatusType())) {
            throw new RuntimeException("不为待审核的领取任务！");
        }
        //验证是否为非法操作
        this.validateIsIllegalOperation(receiveEntity);
        switch (entity.getAuditStatusType()) {
            case "10010004"://通过
                //通过审核
                this.passAuditReceiveJob(receiveEntity);
                break;
            case "10010005"://驳回
                receiveEntity.setAuditStatusType(entity.getAuditStatusType());
                receiveEntity.setRejectReason(entity.getRejectReason());
                itJobReceiveService.updateById(receiveEntity);
                break;
            default:
                throw new RuntimeException("不支持的审核类型");
        }
    }

    @Override
    public PageUtils listReceiveEntity(QueryReceiveJobEntity entity) {
        List<String> jobIdList = new ArrayList<>();
        if (StringUtils.isNotBlank(entity.getReleaseUserId())) {
            Wrapper<TUserJobEntity> jobWrapper = new EntityWrapper<TUserJobEntity>()
                    .where("1=1")
                    .eq("status", "0")
                    .eq("user_id", entity.getReleaseUserId())
                    .setSqlSelect("job_id as jobId");
            List<Map<String, Object>> list = itUserJobService.selectMaps(jobWrapper);
            for (Map<String, Object> map : list) {
                jobIdList.add((String) map.get("jobId"));
            }
        }
        Wrapper<TJobReceiveEntity> wrapper = new EntityWrapper<TJobReceiveEntity>()
                .where("1=1")
                .eq("status", "0")
                .eq(StringUtils.isNotBlank(entity.getJobId()), "job_id", entity.getJobId())
                .eq(StringUtils.isNotBlank(entity.getReceiveUserId()), "user_id", entity.getReceiveUserId())
                .in(!CollectionUtils.isEmpty(jobIdList), "job_id", jobIdList)
                .orderBy("create_time desc");
        Page<TJobReceiveEntity> page = itJobReceiveService.selectPage(new Query<TJobReceiveEntity>(BeanMapUtil.toPageQuery(entity)).getPage(), wrapper);
        List<TJobReceiveEntity> resultList = new ArrayList<>();
        for (TJobReceiveEntity e : page.getRecords()) {
            //扩展图片，顺便补充任务实体
            this.extendsReceiveStepImgList(e);
            resultList.add(e);
        }
        page.setRecords(resultList);
        return new PageUtils(page);
    }

    @Override
    public TJobReceiveEntity getReceiveEntity(String receiveId) {
        TJobReceiveEntity receiveEntity = itJobReceiveService.selectById(receiveId);
        if (null == receiveEntity) {
            throw new RuntimeException("目标领取记录不存在");
        }
        this.extendsReceiveStepImgList(receiveEntity);
        return receiveEntity;
    }

    @Override
    public void removeUserJob(String jobId) {
        TUserJobEntity userJobEntity = itUserJobService.selectById(jobId);
        if (null == userJobEntity) {
            throw new RuntimeException("目标任务不存在");
        }
        Wrapper<TJobReceiveEntity> wrapper = new EntityWrapper<TJobReceiveEntity>()
                .where("1=1")
                .eq("job_id", jobId)
                .ne("audit_status_type", "10010004");
        int count = itJobReceiveService.selectCount(wrapper);
        if (count > 0) {
            throw new RuntimeException("有用户正在做任务，不能删除任务");
        }
        TUserJobEntity jobEntity = new TUserJobEntity();
        jobEntity.setJobId(jobId);
        jobEntity.setStatus("1");
        itUserJobService.updateById(jobEntity);
    }

    @Override
    public Page<TUserJobEntity> listPersonConcernJob(QueryPersonJobEntity entity) {
        int begin = (entity.getPage() - 1) * entity.getLimit();
        int end = entity.getLimit();
        List<TUserJobEntity> jobEntityList = itJobConcernService.listPersonConcernJob(TLMap.getUserId(), begin, end);
        for (TUserJobEntity jobEntity : jobEntityList) {
            //扩展发布者信息
            TUserInfoEntity userInfoEntity = itUserInfoService.selectById(jobEntity.getUserId());
            jobEntity.setUserName(userInfoEntity.getUserName());
            jobEntity.setUserHeadUrl(aliOssUtil.getOssObjectDownAuthUrl(userInfoEntity.getUserHeadUrl()));
            this.extendsToAudit(jobEntity);
            this.extendsConcernReceiveStatus(jobEntity);
            this.extendsJobStep(jobEntity);
            this.extendsCreateUserInfo(jobEntity);//扩展发布用户信息
        }
        int count = itJobConcernService.listPersonConcernJobCount(TLMap.getUserId(), begin, end);
        Page<TUserJobEntity> page = new Page<>();
        page.setRecords(jobEntityList);
        page.setTotal(count);
        page.setSize(entity.getLimit());
        page.setCurrent(entity.getPage());
        return page;
    }

    /**
     * 扩展图片
     *
     * @param e
     */
    private void extendsReceiveStepImgList(TJobReceiveEntity e) {
        Wrapper<TSysImgEntity> wrapper = new EntityWrapper<TSysImgEntity>()
                .where("1=1")
                .eq("business_id", e.getId())
                .orderBy("img_sequence asc");
        List<TSysImgEntity> list = itSysImgService.selectList(wrapper);
        List<String> stepImgList = new ArrayList<>();
        for (TSysImgEntity entity : list) {
            if (!"-1".equals(entity.getImgUrl())) {
                entity.setImgUrl(aliOssUtil.getOssObjectDownAuthUrl(entity.getImgUrl()));
            }
            stepImgList.add(entity.getImgUrl());
        }
        e.setStepImgList(stepImgList);
        //补充任务实体
        TUserJobEntity jobEntity = itUserJobService.selectById(e.getJobId());
        this.extendsJobStep(jobEntity);
        this.extendsConcernReceiveStatus(jobEntity);
        this.extendsToAudit(jobEntity);
        this.extendsCreateUserInfo(jobEntity);//扩展发布用户信息
        e.setJobEntity(jobEntity);
    }

    /**
     * 验证是否为非法操作
     *
     * @param receiveEntity
     */
    private void validateIsIllegalOperation(TJobReceiveEntity receiveEntity) {
        TUserJobEntity jobEntity = itUserJobService.selectById(receiveEntity.getJobId());
        if (!TLMap.getUserId().equals(jobEntity.getUserId())
                && !"1".equals(TLMap.getUserId())) {
            throw new RuntimeException("非法操作，这不是你的任务，不能操作审核");
        }
    }

    /**
     * 通过审核
     *
     * @param receiveEntity
     */
    private void passAuditReceiveJob(TJobReceiveEntity receiveEntity) {
        receiveEntity.setAuditStatusType("10010004");//通过审核
        receiveEntity.setFinishTime(new Date());
        itJobReceiveService.updateById(receiveEntity);
        //操作用户账户，进行上账
        itUserAccountService.alterGoldCoinAmount("10000001", "10001006", TLMap.getUserId(), receiveEntity.getId(), receiveEntity.getAmount());
    }

    /**
     * 校验新增参数
     *
     * @param jobEntity
     */
    private void validateAddJobParam(TUserJobEntity jobEntity) {
        if (StringUtils.isBlank(jobEntity.getTitle())
                || null == jobEntity.getAmount()
                || null == jobEntity.getNumber()
                || StringUtils.isBlank(jobEntity.getApplyCondition())
                || CollectionUtils.isEmpty(jobEntity.getStepList())
                || 0 == jobEntity.getStepList().size()) {
            throw new RuntimeException("必传参数为空！");
        }
    }

    /**
     * 扩展任务步骤
     *
     * @param jobEntity
     */
    private void extendsJobStep(TUserJobEntity jobEntity) {
        Wrapper<TJobStepEntity> wrapper = new EntityWrapper<TJobStepEntity>()
                .where("1=1")
                .eq("job_id", jobEntity.getJobId())
                .orderBy("step_num asc");
        List<TJobStepEntity> list = itJobStepService.selectList(wrapper);
        if (null == list || list.size() == 0) {
            return;
        }
        List<TJobStepEntity> resultList = new ArrayList<>();
        for (TJobStepEntity entity : list) {
            //转化图片地址
            entity.setImgUrl(aliOssUtil.getOssObjectDownAuthUrl(entity.getImgUrl()));
            resultList.add(entity);
        }
        jobEntity.setStepList(resultList);
    }
}
